<?php

namespace app\api\controller\order;

use app\api\controller\Api;
use app\common\audit\logic\AuditResultLogic;
use app\common\customer\model\Customer;
use app\common\customer\model\CustomerAllocate;
use app\common\customer\model\CustomerContact;
use app\common\order\logic\IncomeLogic;
use app\common\order\logic\PaymentLogic;
use app\common\order\model\OrderAdditional;
use app\common\order\model\OrderBanquet;
use app\common\order\model\OrderCollect;
use app\common\order\model\OrderProduct;
use app\common\order\model\OrderIncome;
use app\common\order\model\OrderSettle;
use app\common\order\validate\OrderIncomeValidate;
use app\common\order\validate\OrderProductValidate;
use app\common\order\validate\OrderValidate;
use app\common\system\logic\DepartmentLogic;
use app\common\system\logic\UserDepartmentLogic;
use app\common\system\logic\UserLogic;
use app\common\system\model\OperateLog;
use app\common\system\model\UserConfig;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\Exception;
use util\Format;

class Order extends Api
{
    public function index()
    {
        $post = $this->request->post();
        $user = $this->request->user;

        $where = [];
        $where[] = ['refund_status', '=', 0];
        $where[] = ['transfer_status', '=', 0];
        if ($user['user_type'] == 2) {
            $userLogic = new UserLogic();
            $staffIds = $userLogic->getDptUserIds($user['id']);
            $where[] = ['user_id', 'in', $staffIds];
        } else {
            $where[] = ['user_id', '=', $user['id']];
        }
        if (!empty($post['department_id'])) {
            $dptLogic = new UserDepartmentLogic();
            $staffIds = $dptLogic->getDptUserIds($post['department_id']);
            $where[] = ['user_id', 'in', $staffIds];
        }
        if (!empty($post['user_id'])) $where[] = ['user_id', 'in', $post['user_id']];
        if (!empty($post['company_id'])) $where[] = ['company_id', 'in', $post['company_id']];
        if (!empty($post['store_id'])) $where[] = ['store_id', 'in', $post['store_id']];
        if (!empty($post['category_id'])) $where[] = ['category_id', 'in', $post['category_id']];
        if (!empty($post['order_type'])) $where[] = ['order_type', 'in', $post['order_type']];
        if (!empty($post['check_status'])) $where[] = ['check_status', 'in', $post['check_status']];
        if (!empty($post['cooperation_id'])) $where[] = ['cooperation_id', 'in', $post['cooperation_id']];
        if (!empty($post['sign_date_range'])) {
            $signDateRange = Format::dateRange($post['sign_date_range']);
            $where[] = ['sign_date', 'between', $signDateRange];
        }
        if (!empty($post['event_date_range'])) {
            $eventDateRange = Format::dateRange($post['event_date_range']);
            $where[] = ['event_date', 'between', $eventDateRange];
        }
        if (!empty($post['keyword'])) $where[] = ['contact_no|bridegroom|bridegroom_mobile|bride|bride_mobile', 'like', "%{$post['keyword']}%"];

        list($cfg) = Format::pagination($post);
        $model = new \app\common\order\model\Order();
        $model = $model->where($where);
        if (!empty($post['service_company_id'])) {
            $hasMap = [];
            $hasMap[] = ['company_id', 'in', $post['service_company_id']];
            $model = $model->whereIn('id', function ($query) use ($hasMap) {
                $query->table('tk_order_product')->where($hasMap)->where('delete_time', 0)->field('order_id');
            });
        }
        if (!empty($post['source_id'])) {
            $hasWhere = [];
            $hasWhere[] = ['source_id', 'in', $post['source_id']];
            $model = $model->whereIn('member_id', function ($query) use ($hasWhere) {
                $query->table('tk_member')->where($hasWhere)->where('delete_time', 0)->field('id');
            });
        }
        if (empty($post['is_export'])) {
            // 查询
            $pg = $model->order('id desc')->paginate($cfg);
            $rows = $pg->getCollection();
            foreach ($rows as $row) {
                $row->append(['category', 'company', 'source','cooperation', 'user', 'store', 'hall', 'banquet_type', 'order_type_text', 'check_tag']);
            }

            // 返回接口数据
            $result['list'] = $rows;
            $result['pagination'] = Format::pgResult($pg);

            return success($result, '获取数据成功');
        } else {

            // 审核状态	订单类型 订单性质 所属公司 渠道来源	合同模式 合同编号	签单销售	签约日期	举办日期	新郎姓名	新郎电话	酒店名称	宴会厅	创建时间	
            $header = [
                'check_status' => '审核状态',
                'order_type' => '订单性质',
                'category' => '订单类型',
                'sign_company' => '所属公司',
                'source' => '渠道来源',
                'cooperation' => '合同模式',
                'wedding_company' => '婚庆承办公司',
                'wedding_package' => '婚庆套系',
                'wedding_price' => '婚庆金额',
                'order_no' => '订单号',
                'sales' => '签单销售',
                'sign_date' => '签约日期',
                'event_date' => '举办日期',
                'bridegroom' => '新郎姓名',
                'bridegroom_mobile' => '新郎电话',
                'bride' => '新娘姓名',
                'bride_mobile' => '新娘电话',
                'store' => '酒店名称',
                'hall' => '宴会厅',
                'create_time' => '创建时间',
                'totals' => '合同总金额',
                // 定金
                'earnest_money' => '合同定金',
                // 合同定金收款
                'earnest_date' => '合同定金时间',
                // 定金实收
                'earnest_money_real' => '定金实收',
                // 定金实收时间
                'earnest_real_date' => '定金实收时间',
                // 中款
                'middle_money' => '合同中款',
                // 中款合同时间
                'middle_date' => '合同中款时间',
                // 中款实收
                'middle_money_real' => '中款实收',
                // 中款实收时间
                'middle_real_date' => '中款实收时间',
                // 尾款
                'tail_money' => '合同尾款',
                // 尾款合同时间
                'tail_date' => '合同尾款时间',
                // 尾款实收
                'tail_money_real' => '尾款实收',
                // 尾款实收时间
                'tail_real_date' => '尾款实收时间',
                // 其他金额
                'other_money' => '其他金额',

                // 返佣结算金额
                'rebate_total' => '返佣结算金额',
                // 返佣实际结算金额
                'rebate_real_total' => '返佣实际结算金额',
            ];

            $rows = $model->order('id desc')->select();
            $expData = [];
            foreach ($rows as $row) {
                $attrs = ['customer', 'category', 'wedding', 'cooperation', 'user', 'store', 'hall', 'banquet_type', 'order_type_text', 'contacts', 'collects', 'income', 'rebate', 'check_tag'];
                $row->append($attrs);
                $data = [];
                $data['check_status'] = $row['check_tag'];
                $data['order_type'] = $row['order_type_text'];
                $data['category'] = $row['category']['title'];
                $data['sign_company'] = $row['company']['title'];
                $data['source'] = $row['customer']['source']['title']; // 渠道名称
                $data['cooperation'] = $row['cooperation']['title']; // 合作模式
                $data['wedding_company'] = $row['wedding']['company']['title']; // 婚庆承办公司
                $data['wedding_package'] = $row['wedding']['product']['title']; // 婚庆套系
                $data['wedding_price'] = $row['wedding']['total']; // 婚庆金额
                $data['order_no'] = $row['order_no'];
                $data['sales'] = $row['user']['realname'];
                $data['sign_date'] = $row['sign_date'];
                $data['event_date'] = $row['event_date'];
                $data['bridegroom'] = $row['bridegroom'];
                $data['bridegroom_mobile'] = $row['bridegroom_mobile'];
                $data['bride'] = $row['bride'];
                $data['bride_mobile'] = $row['bride_mobile'];
                $data['store'] = $row['store']['title'];
                $data['hall'] = $row['hall']['title'];
                $data['create_time'] = $row['create_time'];
                $data['totals'] = $row['totals'];
                $collects =  array_column($row['collects'], null, 'type');
                // 定金
                $data['earnest_money'] = isset($collects[1]) ? $collects[1]['price'] : '';
                // 合同定金收款
                $data['earnest_date'] = isset($collects[1]) ? $collects[1]['collect_date'] : '';
                // 定金实收
                $data['earnest_money_real'] = $row['income']['earnest']['total'];
                // 定金实收时间
                $data['earnest_real_date'] = $row['income']['earnest']['date'];

                // 中款
                $data['middle_money'] = isset($collects[2]) ? $collects[2]['price'] : '';
                // 中款合同时间
                $data['middle_date'] = isset($collects[2]) ? $collects[2]['collect_date'] : '';
                // 中款实收
                $data['middle_money_real'] = $row['income']['middle']['total'];
                // 中款实收时间
                $data['middle_real_date'] = $row['income']['middle']['date'];

                // 尾款
                $data['tail_money'] = isset($collect[3]) ? $collects[3]['price'] : '';
                // 尾款合同时间
                $data['tail_date'] = isset($collect[3]) ? $collects[3]['collect_date'] : '';
                // 尾款实收
                $data['tail_money_real'] = $row['income']['tail']['total'];
                // 尾款实收时间
                $data['tail_real_date'] = $row['income']['tail']['date'];

                // 其他金额
                $data['other_money'] = $row['income']['other']['total'];

                // 返佣结算金额
                $data['rebate_total'] = $row['rebate']['total'];
                // 返佣实际结算金额
                $data['rebate_real_total'] = $row['rebate']['real_total'];

                $expData[] = $data;
            }

            // print_r($expData);
            $fileName = '【订单】' . date('YmdHis');
            $url = \app\common\third\Excel::exportExcel($expData, $header, $fileName);
            return success(['url' => $url], '导出成功');
        }
    }

    public function plan()
    {
        $post = $this->request->post();
        $user = $this->request->user;

        $where = [];
        if (!empty($post['user_id'])) $where[] = ['user_id', 'in', $post['user_id']];
        if (!empty($post['company_id'])) $where[] = ['company_id', 'in', $post['company_id']];
        if (!empty($post['store_id'])) $where[] = ['store_id', 'in', $post['store_id']];
        if (!empty($post['category_id'])) $where[] = ['category_id', 'in', $post['category_id']];
        if ($user['user_type'] == 2) { // 管理者
            $configModel = new UserConfig();
            $config = $configModel->where('id', $user['id'])->find();
            if (empty($config)) {
                $where[] = ['company_id', 'in', []];
            } else {
                $where[] = ['company_id', 'in', $config['company']];
            }
        }
        if (!empty($post['assign_status'])) $where[] = ['assign_status', '=', $post['assign_status']];
        if (!empty($post['order_type'])) $where[] = ['order_type', 'in', $post['order_type']];
        if (!empty($post['check_status'])) $where[] = ['check_status', 'in', $post['check_status']];
        if (!empty($post['sign_date_range'])) {
            $signDateRange = Format::dateRange($post['sign_date_range']);
            $where[] = ['sign_date', 'between', $signDateRange];
        }
        if (!empty($post['event_date_range'])) {
            $eventDateRange = Format::dateRange($post['event_date_range']);
            $where[] = ['event_date', 'between', $eventDateRange];
        }
        $where[] = ['refund_status', '=', 0];
        if (!empty($post['keyword'])) $where[] = ['contact_no|bridegroom|bridegroom_mobile|bride|bride_mobile', 'like', "%{$post['keyword']}%"];


        list($cfg) = Format::pagination($post);
        $model = new \app\common\order\model\Order();
        $model = $model->where($where);
        if (!empty($post['service_company_id'])) {
            $hasMap = [];
            $hasMap[] = ['company_id', 'in', $post['service_company_id']];
            $model = $model->whereIn('id', function ($query) use ($hasMap) {
                $query->table('tk_order_product')->where($hasMap)->field('order_id');
            });
        }
        if (!empty($post['source_id'])) {
            $hasWhere = [];
            $hasWhere[] = ['source_id', 'in', $post['source_id']];
            $model = $model->whereIn('member_id', function ($query) use ($hasWhere) {
                $query->table('tk_member')->where($hasWhere)->field('id');
            });
        }

        // 策划
        if ($user['user_type'] != 2) {
            $model = $model->whereIn('id', function ($query) use ($user) {
                $query->table('tk_order_user')->where('user_id', $user['id'])->where('role_id', 17)->field('order_id');
            });
        }

        if (!empty($post['planner_id'])) {
            $planWhere = [];
            $planWhere[] = ['user_id', 'in', $post['planner_id']];
            $planWhere[] = ['role_id', '=', 17];
            $model = $model->whereIn('id', function ($query) use ($planWhere) {
                $query->table('tk_order_user')->where($planWhere)->field('order_id');
            });
        }

        $pg = $model->order('id desc')->paginate($cfg);
        $rows = $pg->getCollection();
        foreach ($rows as $row) {
            $row->append(['category', 'company', 'cooperation', 'user', 'store', 'hall', 'banquet_type', 'order_type_text', 'check_tag']);
        }

        // 返回接口数据
        $result['list'] = $rows;
        $result['pagination'] = Format::pgResult($pg);

        return success($result, '获取数据成功');
    }

    public function schedule()
    {
        $post = $this->request->post();
        $user = $this->request->user;

        if (empty($post['store_id'])) return error([], "缺少store_id参数");
        if (empty($post['hall_id'])) return error([], "缺少hall_id参数");
        if (empty($post['month'])) return error([], "缺少month参数");

        $where = [];
        $where[] = ['store_id', '=', $post['store_id']];
        $where[] = ['hall_id', '=', $post['hall_id']];
        $where[] = ['refund_status', '=', 0];
        $where[] = ['transfer_status', '=', 0];
        $where[] = ['event_date', 'between', Format::monthRange($post['month'])];

        $model = new \app\common\order\model\Order();
        $rows = $model->where($where)->field('id,category_id,event_date')->select();
//        echo $model->getLastSql();
        foreach ($rows as $row) {
            $row->append(['category']);
        }

        // 按照日期分组
        $group = [];
        foreach ($rows as $row) {
            $group[$row['event_date']][] = $row;
        }

        return success($group, '获取数据成功');
    }

    public function refund()
    {
        $post = $this->request->post();
        $user = $this->request->user;

        $where = [];
        $where[] = ['refund_status', '=', '1'];
        if ($user['user_type'] == 2) {
            $userLogic = new UserLogic();
            $staffIds = $userLogic->getDptUserIds($user['id']);
            $where[] = ['user_id', 'in', $staffIds];
        } else {
            $where[] = ['user_id', '=', $user['id']];
        }
        if (!empty($post['department_id'])) {
            $dptLogic = new UserDepartmentLogic();
            $staffIds = $dptLogic->getDptUserIds($post['department_id']);
            $where[] = ['user_id', 'in', $staffIds];
        }
        if (!empty($post['user_id'])) $where[] = ['user_id', 'in', $post['user_id']];
        if (!empty($post['company_id'])) $where[] = ['company_id', 'in', $post['company_id']];
        if (!empty($post['store_id'])) $where[] = ['store_id', 'in', $post['store_id']];
        if (!empty($post['category_id'])) $where[] = ['category_id', 'in', $post['category_id']];
        if (!empty($post['order_type'])) $where[] = ['order_type', 'in', $post['order_type']];
        if (!empty($post['check_status'])) $where[] = ['check_status', 'in', $post['check_status']];
        if (!empty($post['sign_date_range'])) {
            $signDateRange = Format::dateRange($post['sign_date_range']);
            $where[] = ['sign_date', 'between', $signDateRange];
        }
        if (!empty($post['event_date_range'])) {
            $eventDateRange = Format::dateRange($post['event_date_range']);
            $where[] = ['event_date', 'between', $eventDateRange];
        }
        if (!empty($post['keyword'])) $where[] = ['contact_no|bridegroom|bridegroom_mobile|bride|bride_mobile', 'like', "%{$post['keyword']}%"];


        list($cfg) = Format::pagination($post);
        $model = new \app\common\order\model\Order();
        $model = $model->where($where);
        if (!empty($post['service_company_id'])) {
            $hasMap = [];
            $hasMap[] = ['company_id', 'in', $post['service_company_id']];
            $model = $model->whereIn('id', function ($query) use ($hasMap) {
                $query->table('tk_order_product')->where($hasMap)->field('order_id');
            });
        }
        if (!empty($post['source_id'])) {
            $hasWhere = [];
            $hasWhere[] = ['source_id', 'in', $post['source_id']];
            $model = $model->whereIn('member_id', function ($query) use ($hasWhere) {
                $query->table('tk_member')->where($hasWhere)->field('id');
            });
        }
        $pg = $model->order('id desc')->paginate($cfg);
        $rows = $pg->getCollection();
        foreach ($rows as $row) {
            $row->append(['category', 'company', 'cooperation', 'user', 'store', 'hall', 'banquet_type', 'order_type_text', 'check_tag']);
        }

        // 返回接口数据
        $result['list'] = $rows;
        $result['pagination'] = Format::pgResult($pg);

        return success($result, '获取数据成功');
    }

    // 订单详情
    public function detail()
    {
        $post = $this->request->post();
        

        // 付款简介
        return success([]);
    }

    // 创建订单
    public function create()
    {
        $post = $this->request->post();

        $user = $this->request->user;
        if (!isset($post['main'])) {
            return error([], "缺少订单借本信息参数");
        }

        $main = $post['main'];
        $main['user_id'] = $user['id'];
        $orderModel = new \app\common\order\model\Order();
        $orderModel->startTrans();
        try {
            $orderModel->save($main);
            $orderId = $orderModel->id;
        } catch (DbException $e) {
            $orderModel->rollback();
            return error([], $e->getMessage());
        }

       
        $products = $post['product'];
        foreach ($products as $key => $product) {
            $product['order_id'] = $orderId;
            $product['user_id'] = $user['id'];
            $product['category_id'] = $key;
            $productModel = new OrderBanquet();
            try {   
                $productModel->save($product);
            } catch (DbException $e) {
                $orderModel->rollback();
                return error([], $e->getMessage());
            }
        }

        $orderModel->commit();
        return success([], '创建订单成功');
    }

    public function save()
    {
        $post = $this->request->post();

        $user = $this->request->user;
        if (!isset($post['order'])) {
            return error([], "缺少order参数");
        }

        if (!isset($post['products'])) {
            return error([], "缺少products参数");
        }

        if (!isset($post['income'])) {
            return error([], "缺少income参数");
        }

        // 验证订单基本信息
        $order = $post['order'];
        $orderValidate = new OrderValidate();
        if (!$orderValidate->check($order)) {
            return error([], $orderValidate->getError());
        }

        // 验证产品信息
        $products = $post['products'];
        foreach ($products as $product) {
            $orderProductValidate = new OrderProductValidate();
            if (!$orderProductValidate->check($product)) {
                return error([], $orderProductValidate->getError());
            }
        }

        // 验证收款信息
        $income = $post['income'];
        $incomeValidate = new OrderIncomeValidate();
        if (!$incomeValidate->check($income)) {
            return error([], $incomeValidate->getError());
        }

        $order['user_id'] = $user['id'];
        $model = new \app\common\order\model\Order();
        $model->startTrans();
        $source = [];
        try {
            $orderRow = $model->where('id', $order['id'])->find();
            $orderRow->save($order);
            $orderId = $order['id'];

            $modelName = \app\common\order\model\Order::class;
            $source[$modelName] = $orderId;
        } catch (DbException $e) {
            $model->rollback();
            return error([], $e->getMessage());
        }

        // 同步收款计划
        $collects = $post['order']['collects'];
        $collectModel = new OrderCollect();
        foreach ($collects as &$row) {
            $row['order_id'] = $orderId;
            $collect = $collectModel->where('id', $row['id'])->find();
            $collect->save($row);
        }

        // 服务类型
        $modelName = OrderProduct::class;
        foreach ($products as $row) {

            $row['order_id'] = $orderId;
            $row['user_id'] = $user['id'];
            try {
                $orderProductModel = new OrderProduct();
                if ($row['id']) {
                    $product = $orderProductModel->where('id', $row['id'])->find();
                    $product->save($row);
                    $source[$modelName][] = $row['id'];
                } else {
                    $orderProductModel->save($row);
                    $source[$modelName][] = $orderProductModel->id;
                }
            } catch (DbException $e) {
                $model->rollback();
                return error([], $e->getMessage());
            }
        }

        // 收款信息
        $income['order_id'] = $orderId;
        $income['user_id'] = $user['id'];
        $incomeModel = new OrderIncome();
        $modelName = OrderIncome::class;
        try {
            $incomeRow = $incomeModel->where('id', $income['id'])->find();
            $incomeRow->save($income);
            $source[$modelName] = $income['id'];
        } catch (DbException $e) {
            $model->rollback();
            return error([], $e->getMessage());
        }

        // 添加增项
        if (!empty($post['additional'])) {
            $modelName = OrderAdditional::class;
            $additionals = $post['additional'];
            foreach ($additionals as $row) {
                try {
                    $row['order_id'] = $orderId;
                    $row['user_id'] = $user['id'];
                    $additionalModel = new OrderAdditional();
                    if ($row['id']) {
                        $additional = $additionalModel->where('id', $row['id'])->find();
                        $additional->save($row);
                        $source[$modelName][] = $row['id'];
                    } else {
                        $additionalModel->save($row);
                        $source[$modelName][] = $additionalModel->id;
                    }
                } catch (DbException $e) {
                    $model->rollback();
                    return error([], $e->getMessage());
                }
            }
        }

        // 未找到审核流程可重新发起暂存
        // if ($order['check_status'] == -1) {
        //     return success([], "暂存成功");
        // }

        $auditRsLogic = new AuditResultLogic();
        $master = $orderRow->getData();
        $options = [
            'company_id' => $master['company_id'],
            'timing' => 'order'
        ];
        try {
            $auditNo = $auditRsLogic->initAudit($master, $user, $source, $options);
            foreach ($source as $className => $row) {
                try {
                    $where = [];
                    if (is_array($row)) {
                        $where[] = ['id', 'in', $row];
                    } else {
                        $where[] = ['id', '=', $row];
                    }
                    $class = new $className;
                    $class->where($where)->save(['check_no' => $auditNo]);
                } catch (DbException $e) {
                    return error([], $e->getMessage());
                }
            }
            $model->commit();

            return success([], '创建订单成功');
        } catch (Exception $e) {
            $msg = $e->getMessage();
        } catch (DbException $e) {
            $msg = $e->getMessage();
        }
        return error([], $msg, 404);
    }

    public function update()
    {
        $post = $this->request->post();
        $user = $this->request->user;

        $orderValidate = new OrderValidate();
        if (!$orderValidate->check($post)) {
            return error([], $orderValidate->getError());
        }

        $model = new \app\common\order\model\Order();
        $row = $model->where('id', $post['id'])->find();
        if (empty($row)) return error([], '数据已不存在');

        $model->startTrans();
        try {
            // $post['user_id'] = $user['id'];
            $origin = $row->getData();
            $row->save($post);

            $changed = $row->getData();
            $modelName = \app\common\order\model\Order::class;
            OperateLog::write($user['id'], $post['id'], $origin, $changed, $modelName);
        } catch (DbException $e) {
            $model->rollback();
            return error([], $e->getMessage());
        }
        $model->commit();

        return success([], '更新成功');
    }

    public function doRefund()
    {
        $post = $this->request->post();
        $user = $this->request->user;

        if (empty($post['id'])) return error([], "参数错误");

        $model = new \app\common\order\model\Order();
        $row = $model->field('id,refund_status')->where('id', $post['id'])->find();
        if (empty($row)) return error([], '数据已不存在');

        $model->startTrans();
        try {
            $origin = $row->getData();
            $post['refund_status'] = 1;
            $row->save($post);

            $changed = $row->getData();
            $modelName = \app\common\order\model\Order::class;
            OperateLog::write($user['id'], $post['id'], $origin, $changed, $modelName);
        } catch (DbException $e) {
            $model->rollback();
            return error([], $e->getMessage());
        }
        $model->commit();

        return success([], '退单成功');
    }

    public function updateContract()
    {
        $post = $this->request->post();
        $user = $this->request->user;
        if (empty($post['id'])) return error([], "参数错误");

        if (empty($post['contract'])) return error([], "请上传客情附件");

        $model = new \app\common\order\model\Order();
        $row = $model->where('id', $post['id'])->find();
        if (empty($row)) return error([], '数据已不存在');

        $model->startTrans();
        try {
            $origin = $row->getData();
            $update = [];
            $update['contract'] = $post['contract'];
            $row->save($update);

            $changed = $row->getData();
            $modelName = \app\common\order\model\Order::class;
            OperateLog::write($user['id'], $post['id'], $origin, $changed, $modelName);
        } catch (DbException $e) {
            $model->rollback();
            return error([], $e->getMessage());
        }

        $model->commit();
        // return success
        return success([], '更新成功');
    }
}
